import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * https://segmentfault.com/a/1190000037714804
 *
 * @author songxulin
 * @date 2023/9/19 17:05
 * @version 1.0
 */
public class SimpleNIOHttpServer {
    volatile static AtomicInteger count = new AtomicInteger(0);
    public static void main(String[] args) {
        int port = 8080;
        try {
            // 创建ServerSocketChannel并绑定端口
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.socket().bind(new InetSocketAddress(port));
            serverChannel.configureBlocking(false);

            // 创建Selector并注册ServerSocketChannel
            Selector selector = Selector.open();
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);

            System.out.println("Server is listening on port " + port);

            while (true) {
                selector.select();

                Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();

                while (keyIterator.hasNext()) {
                    SelectionKey key = keyIterator.next();
                    keyIterator.remove();

                    if (key.isAcceptable()) {
                        // 处理新的连接请求
                        handleAccept(key, selector);
                    } else if (key.isReadable()) {
                        // 处理已连接的Socket的读取请求
                        handleRead(key);

                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void handleAccept(SelectionKey key, Selector selector) throws IOException {
        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
        SocketChannel clientChannel = serverChannel.accept();
        clientChannel.configureBlocking(false);
        clientChannel.register(selector, SelectionKey.OP_READ);
//        System.out.println(count.getAndIncrement());
    }

    private static void handleRead(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        StringBuilder request = new StringBuilder();

        int bytesRead;
        while ((bytesRead = channel.read(buffer)) > 0) {
            buffer.flip();
            while (buffer.hasRemaining()) {
                request.append((char) buffer.get());
            }
            buffer.clear();
        }
        System.out.println("Accepted connection from " +key.toString());
        String httpRequest = request.toString();
        System.out.println("Received request:\n" + httpRequest);

        // 处理HTTP请求，这里可以编写你的业务逻辑
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 响应客户端
        String httpResponse = "HTTP/1.1 200 OK\r\n\r\nHello, World!";
        ByteBuffer responseBuffer = ByteBuffer.wrap(httpResponse.getBytes());
        while (responseBuffer.hasRemaining()) {
            channel.write(responseBuffer);
        }
        channel.close();
    }
}

